package main

import (
	"fmt"
	"sync"
)

var (
	instance *Singleton
	mu       sync.Mutex
	once     sync.Once
)

type Singleton struct {
	// ？？？？？？？ 试说明如果是空结构体，无需单例模式，多次创建并不会重新分配内存，
	//struct 就是普通的一个内存块，必定是占用一小块内存的
	//但是“空结构体”是不占内存的，size 为 0；在 golang 里面，
	//涉及到所有内存 size 为 0 的内存分配，那么就是用的同一个地址
	name string
}

func (s *Singleton) Hello() {

}

// GetInstance1 懒汉式,其特点是在首次使用时创建单例实例
func GetInstance1() *Singleton {
	once.Do(func() {
		fmt.Println(1)
		instance = &Singleton{}
	})

	return instance
}

// GetInstance2 使用了互斥锁实现并发控制
func GetInstance2() *Singleton {
	if instance == nil {
		mu.Lock() // 注意，锁不能放在下面的那个判断nil的条件语句里
		defer mu.Unlock()
		if instance == nil {
			fmt.Println(2)
			i := Singleton{}
			println(&i)
			instance = &i
		}
	}
	return instance
}

func main() {
	var wg sync.WaitGroup
	f := func() {
		GetInstance2()
		wg.Done()
	}
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go f()
	}
	wg.Wait()
	fmt.Println("singleton.go")

	//c := 0
	//for i := 0; i < 1000; i++ {
	//	go func() {
	//		c = c + 1 // write i
	//	}()
	//}
	//time.Sleep(time.Second * 3)
	//fmt.Println(c) // read i
}
